/*
 * IndividualTest.java
 *
 *  
 */
package org.msb.finance.data;

import static org.junit.Assert.*;

import java.util.Calendar;
import java.util.Date;

import org.junit.Before;
import org.junit.Test;

/**
 * 
 * 
 * @author Marc
 * 
 */
@SuppressWarnings("nls")
public class IndividualTest {

	/*
	 * 
	 */
	private Individual individual;

	/**
	 * 
	 * @throws Exception
	 */
	@Before
	public void setUp() throws Exception {
		this.individual = new Individual();
	}

	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void testGetAge() throws Exception {
		Date dateOfBirth = new Date(-58474800000L);
		Date today = new Date(1201669200000L);

		this.individual.setDateOfBirth(dateOfBirth);
		assertEquals(39, this.individual.getAge(today));
	}

	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void testGetAgeOnBirthDay() throws Exception {
		Date dateOfBirth = new Date(-58474800000L);
		Date today = new Date(1203829200000L);

		this.individual.setDateOfBirth(dateOfBirth);
		assertEquals(40, this.individual.getAge(today));
	}

	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void testAddDependent() throws Exception {
		Individual dependent = new Individual();

		this.individual.addDependent(dependent);

		assertNotNull(this.individual.getDependents());
		assertEquals(1, this.individual.getDependents().size());
	}

	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void testRemoveDependent() throws Exception {
		Individual d1 = new Individual();
		Individual d2 = new Individual();

		this.individual.addDependent(d1);
		this.individual.addDependent(d2);

		assertEquals(2, this.individual.getDependents().size());
		assertTrue(this.individual.getDependents().contains(d1));
		assertTrue(this.individual.getDependents().contains(d2));

		this.individual.removeDependent(d1);

		assertEquals(1, this.individual.getDependents().size());
		assertTrue(this.individual.getDependents().contains(d2));
		assertFalse(this.individual.getDependents().contains(d1));

		this.individual.removeDependent(d1);

		assertEquals(1, this.individual.getDependents().size());
		assertTrue(this.individual.getDependents().contains(d2));
		assertFalse(this.individual.getDependents().contains(d1));

		this.individual.removeDependent(d2);

		assertEquals(0, this.individual.getDependents().size());
		assertFalse(this.individual.getDependents().contains(d2));
		assertFalse(this.individual.getDependents().contains(d1));
	}

	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetShortName() throws Exception {
		final String NAME = "Fred";
		final String NAME2 = "John";

		this.individual.setShortName(NAME);
		assertEquals(NAME, this.individual.getShortName());

		this.individual.setShortName(NAME2);
		assertEquals(NAME2, this.individual.getShortName());
	}

	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetFullName() throws Exception {
		final String NAME = "Fred Smith";
		final String NAME2 = "John Hancock";

		this.individual.setFullName(NAME);
		assertEquals(NAME, this.individual.getFullName());

		this.individual.setFullName(NAME2);
		assertEquals(NAME2, this.individual.getFullName());
	}

	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetDateOfBirth() throws Exception {
		final Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.HOUR, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		calendar.set(1975, 05, 25);

		final Date DOB = calendar.getTime();

		calendar.set(1980, 10, 30);
		final Date DOB2 = calendar.getTime();

		this.individual.setDateOfBirth(DOB);
		assertEquals(DOB, this.individual.getDateOfBirth());

		this.individual.setDateOfBirth(DOB2);
		assertEquals(DOB2, this.individual.getDateOfBirth());

		calendar.setTime(new Date());
		calendar.set(Calendar.MINUTE, 3);
		final Date DOB3 = calendar.getTime();

		this.individual.setDateOfBirth(DOB3);
		assertFalse(DOB3.equals(this.individual.getDateOfBirth()));
	}

	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetSIN() throws Exception {
		final String SIN = "000 000 000";
		final String SIN2 = "123 486 789";

		this.individual.setSin(SIN);
		assertEquals(SIN, this.individual.getSin());

		this.individual.setSin(SIN2);
		assertEquals(SIN2, this.individual.getSin());

		this.individual.setSin(null);
		assertNull(this.individual.getSin());
	}

	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetSpouseToNull() throws Exception {
		assertNull(this.individual.getSpouse());
		this.individual.setSpouse(null);
		assertNull(this.individual.getSpouse()); //$NON-NLS-1$
	}

	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetSpouseToNullWithExistingSpouse() throws Exception {
		Individual oldSpouse = new Individual();
		this.individual.setSpouse(oldSpouse);
		assertSame(oldSpouse, this.individual.getSpouse());

		this.individual.setSpouse(null);
		assertNull(this.individual.getSpouse());
		assertNull(oldSpouse.getSpouse());
	}

	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetSpouseToAttachedIndividualWithExistingSpouse() throws Exception {
		Individual b = new Individual();
		this.individual.setSpouse(b);

		Individual c = new Individual();
		Individual d = new Individual();
		c.setSpouse(d);

		assertSame(b, this.individual.getSpouse());
		assertSame(this.individual, b.getSpouse());
		assertSame(c, d.getSpouse());
		assertSame(d, c.getSpouse());

		this.individual.setSpouse(c);
		assertSame(c, this.individual.getSpouse());
		assertSame(this.individual, c.getSpouse());
		assertNull(b.getSpouse());
		assertNull(d.getSpouse());
	}

	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetSpouseToAttachedIndividualWithNoExistingSpouse() throws Exception {
		Individual c = new Individual();
		Individual d = new Individual();

		c.setSpouse(d);
		assertSame(c, d.getSpouse());
		assertSame(d, c.getSpouse());
		assertNull(this.individual.getSpouse());

		this.individual.setSpouse(c);
		assertSame(c, this.individual.getSpouse());
		assertSame(this.individual, c.getSpouse());
		assertNull(d.getSpouse());
	}

	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetSpouseToSameSpouse() throws Exception {
		Individual b = new Individual();

		this.individual.setSpouse(b);
		assertSame(b, this.individual.getSpouse());
		assertSame(this.individual, b.getSpouse());

		this.individual.setSpouse(b);
		assertSame(b, this.individual.getSpouse());
		assertSame(this.individual, b.getSpouse());
	}

	/**
	 * Test method for {@link org.msb.finance.data.Individual#setSpouse(org.msb.finance.data.Individual)}.
	 * 
	 * @throws Exception
	 */
	@Test
	public void testSetSpouseToSelf() throws Exception {
		try {
			this.individual.setSpouse(this.individual);
			fail("Expected an IllegalArgumentException to be thrown.");
		} catch (IllegalArgumentException ex) {
			// Pass.
		}
	}

	/**
	 * 
	 * @throws Exception
	 */
	@Test
	public void testCompareTo() throws Exception {
		this.individual.setFullName("Fred Smith");

		Individual i1 = new Individual();
		i1.setFullName("AAA-Fred Smith");
		Individual i2 = new Individual();
		i2.setFullName("ZZZ-Fred Smith");

		assertEquals(0, this.individual.compareTo(this.individual));

		assertTrue(0 < this.individual.compareTo(i1));
		assertTrue(0 > this.individual.compareTo(i2));

		this.individual.setFullName(null);
		Individual i3 = new Individual();

		assertEquals(0, this.individual.compareTo(i3));

		this.individual.setFullName("Fred Smith");
		assertEquals(1, this.individual.compareTo(i3));

		i3.setFullName("ZZZ-Fred Smith");
		this.individual.setFullName(null);
		assertEquals(-1, this.individual.compareTo(i3));
	}
}
